﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using System.Threading;
using PowerTriggersWcf;

namespace PowerTriggersService
{
    public partial class Service : ServiceBase
    {
        private ServiceHost host;

        public Service()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
#if DEBUG
            Debugger.Break();
#endif
            try
            {
                base.OnStart(args);
                //EventLogHelper.LogInformation("Power Triggers windows service starting, phase 1");

                Type serviceType = typeof(PowerTriggersWcf.Service);
                //EventLogHelper.LogInformation("Power Triggers windows service starting, phase 1a");
                host = new ServiceHost(serviceType);
                //EventLogHelper.LogInformation("Power Triggers windows service starting, phase 1b");

                host.Open(); // TODO - this is sometimes slow to execute.  Don't know why.  can take up to a minute to start

                // Note, a windows service does not have message loops by default, therefore it will not handle SystemEvents. 
                // to work around this, a form has to be created and this will invoke message loops, thereby allowing the SystemEvents class to work
                // see the following MSDN page for details: http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.aspx
                // With hindsight, this may have been done better with an ApplicationContext based class

                //EventLogHelper.LogInformation("Power Triggers windows service starting, phase 2");

                Thread messagePumpThread = new Thread(PowerTriggersWcf.Service.StartUp);
                messagePumpThread.Name = "MessagePumpThread";
                messagePumpThread.IsBackground = true;
                messagePumpThread.Start();
                while (!messagePumpThread.IsAlive)
                {
                    Thread.Sleep(1);
                }
                Thread.Sleep(100); // give the thread chance to do some work before we continue with service startup
                //PowerTriggersWcf.Service.AddHistoryHeader(HistorySeverityLevels.Informational, "Power Triggers windows service started");
            }
            catch (System.Exception ex)
            {
                EventLogHelper.LogError("Service.OnStart", ex);
                throw;
            }
        }

        protected override void OnStop()
        {
            base.OnStop();
            try
            {
                PowerTriggersWcf.Service.ShutDown();
                //PowerTriggersWcf.Service.AddHistoryHeader(HistorySeverityLevels.Informational, "Power Triggers windows service stopped");
                if (host != null)
                {
                    host.Close();
                    host = null;
                }
            }
            catch (System.Exception ex)
            {
                EventLogHelper.LogError("Service.OnStop", ex);
                throw;
            }
        }

        protected override void OnShutdown()
        {
            base.OnShutdown();
            try
            {
                PowerTriggersWcf.Service.ShutDown();
                //PowerTriggersWcf.Service.AddHistoryHeader(HistorySeverityLevels.Informational, "Power Triggers windows service shutdown");
                if (host != null)
                {
                    host.Close();
                    host = null;
                }
            }
            catch (System.Exception ex)
            {
                EventLogHelper.LogError("Service.OnStop", ex);
                throw;
            }
        }

        protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
        {
            // This might be useful in future versions as a way of handling other powerstate changes
            return base.OnPowerEvent(powerStatus);
        }
    }
}
